import { forwardRef, useImperativeHandle, useRef, useState } from 'react';

import { useRequest } from 'ahooks';
import { AutoComplete, Button, Drawer, Form, FormProps, Input, Radio, Select, Space } from 'antd';

import { store } from '@/store';

import { TimeSort } from '@/enum';
import { DataAuthWhereTypeObj } from '@/enum/api';
import { permissionApiGetTableName } from '@/services/base/quanxianmokuaihouduanjiekouxinxijiekou';
import {
  roleDataPermissionAdd,
  roleDataPermissionGetColumnName,
  roleDataPermissionGetOperateType,
  roleDataPermissionGetRelationType,
  roleDataPermissionUpdate
} from '@/services/base/quanxianmokuaijiaoseshujuquanxianpeizhixinxijiekou';
import { dataPermissionTemplatePage } from '@/services/base/quanxianmokuaishujuquanxianmobanxinxijiekou';

import { BizObject } from '.';

type EditOpenBaseArgs = {
  /** 成功回调 */
  onSuccess?: () => void;
};

export type EditRef = {
  open: (
    arg:
      | (EditOpenBaseArgs & {
          type: 'add';
        })
      | (EditOpenBaseArgs & {
          type: 'edit';
          rowData: BizObject;
        })
      | (EditOpenBaseArgs & {
          type: 'detail';
          rowData: BizObject;
        })
  ) => void;
};

export type EditProps = {
  role?: BASE.Role;
};

const Edit: React.ForwardRefRenderFunction<EditRef, EditProps> = ({ role }, ref) => {
  const [form] = Form.useForm();
  // 弹窗开启状态
  const [open, setOpen] = useState(false);
  const [args, setArgs] = useState<ArgumentsType<EditRef['open']>[0]>();
  // 表列表
  const tableList = useRequest(async () => {
    return (await permissionApiGetTableName()).data;
  });
  // 表字段列表
  const fieldList = useRequest(
    async (tableName: string) => {
      fieldList.mutate(undefined);
      return (await roleDataPermissionGetColumnName({ tableName })).data;
    },
    {
      manual: true
    }
  );
  // 比较类型
  const whereType = useRequest(async () => {
    return (await roleDataPermissionGetOperateType()).data;
  });
  // 关联关系
  const incidenceRelation = useRequest(async () => {
    return (await roleDataPermissionGetRelationType()).data;
  });
  // 模板列表
  const template = useRequest(async () => {
    return (await dataPermissionTemplatePage({ page: 1, size: 9999, timeSort: TimeSort.倒序 })).data
      ?.records;
  });
  // 选择的模版
  const selectedTemplate = useRef<number>();
  const submit = useRequest(
    async (values) => {
      const query = {
        ...values,
        roleId: role?.id
      };

      if (args?.type === 'edit' && args.rowData) {
        query.id = args.rowData.id;
      }

      await (args?.type === 'edit'
        ? roleDataPermissionUpdate(query)
        : roleDataPermissionAdd(query));

      args?.onSuccess?.();
      setOpen(false);

      store.app?.message.success(args?.type === 'edit' ? '编辑成功' : '新增成功');
    },
    {
      manual: true
    }
  );

  useImperativeHandle(ref, () => {
    return {
      open: (args) => {
        setArgs(args);
        setOpen(true);

        setTimeout(() => {
          // 编辑回填数据
          if ((args?.type === 'edit' || args?.type === 'detail') && args?.rowData) {
            // 回填数据
            form.setFieldsValue(args.rowData);
          } else {
            form.resetFields();
          }
        });
      }
    };
  });

  const onFinish: FormProps['onFinish'] = async (values) => {
    return submit.runAsync(values);
  };

  const onCancel = () => {
    if (submit.loading) {
      store.app?.message.info('正在提交中，请稍后');

      return;
    }

    setOpen(false);
  };

  // 选择模版
  const onTemlateSelect = () => {
    store.app?.modal.confirm({
      title: '选择模版',
      content: (
        <Select
          onChange={(e) => {
            selectedTemplate.current = e;
          }}
          style={{
            width: '100%'
          }}
          placeholder="选择数据模板"
          options={template.data?.map((item) => ({ label: item.name, value: item.id }))}
        />
      ),
      onOk: () => {
        const find = template.data?.find((item) => item.id === selectedTemplate.current);

        if (find) {
          form.setFieldsValue(find);
          selectedTemplate.current = undefined;
        }
      }
    });
  };

  return (
    <Drawer
      title={
        {
          add: '新增数据权限',
          edit: '编辑数据权限',
          detail: '数据权限详情'
        }[args?.type as string]
      }
      extra={
        <Space>
          <Button onClick={onTemlateSelect}>选择模版</Button>

          <Button
            type="primary"
            loading={submit.loading}
            disabled={submit.loading}
            onClick={form.submit}
          >
            保存
          </Button>
          <Button onClick={onCancel} disabled={submit.loading}>
            取消
          </Button>
        </Space>
      }
      width="50%"
      open={open}
      onClose={onCancel}
    >
      <Form
        onFinish={onFinish}
        form={form}
        layout="horizontal"
        labelCol={{ span: 6 }}
        wrapperCol={{ span: 14 }}
        initialValues={{}}
        requiredMark={args?.type !== 'detail'}
        variant={args?.type === 'detail' ? 'borderless' : undefined}
      >
        <Form.Item
          label="表名"
          name="tableName"
          rules={[
            {
              required: true,
              message: '请输入表名'
            }
          ]}
        >
          <Select
            showSearch
            filterOption={(input, option) => {
              return ((option?.label as string) ?? '').toLowerCase().includes(input.toLowerCase());
            }}
            options={tableList.data?.map((item) => ({ label: item, value: item }))}
            placeholder="请输入表名"
            allowClear
            onChange={(e) => {
              form.resetFields(['whereField']);

              if (e) {
                fieldList.run(e);
              }
            }}
          />
        </Form.Item>
        <Form.Item dependencies={['tableName']} noStyle>
          {() => {
            const tableName = form.getFieldValue('tableName');

            if (tableName) {
              return (
                <>
                  <Form.Item label="字段名" name="whereField">
                    <AutoComplete
                      options={fieldList.data?.map((item) => ({ label: item, value: item }))}
                      placeholder="请输入字段名"
                    />
                  </Form.Item>
                </>
              );
            }

            return null;
          }}
        </Form.Item>
        <Form.Item
          label="比较类型"
          name="whereType"
          rules={[
            {
              required: true,
              message: '请选择比较类型'
            }
          ]}
        >
          <Radio.Group>
            {whereType.data?.map((item) => (
              <Radio value={item.operator} key={item.operator}>
                {item.operateName}
              </Radio>
            ))}
          </Radio.Group>
        </Form.Item>
        <Form.Item
          label="值"
          name="whereValue"
          rules={[
            {
              required: true,
              message: '请输入值'
            }
          ]}
        >
          <Input.TextArea placeholder="请输入值" />
        </Form.Item>
        <Form.Item
          label="值类型"
          name="whereValueType"
          rules={[
            {
              required: true,
              message: '请选择值类型'
            }
          ]}
        >
          <Radio.Group>
            {Array.from(DataAuthWhereTypeObj).map(([key, value]) => (
              <Radio value={key} key={key}>
                {value.text}
              </Radio>
            ))}
          </Radio.Group>
        </Form.Item>
        <Form.Item label="join表达式" name="expression">
          <Input.TextArea placeholder="请输入join表达式" />
        </Form.Item>
        <Form.Item label="bean名称" name="implBeanName">
          <Input.TextArea placeholder="请输入bean名称" />
        </Form.Item>
        <Form.Item label="关联关系" name="incidenceRelation">
          <Radio.Group>
            {incidenceRelation.data?.map((item) => (
              <Radio value={item.operator} key={item.operator}>
                {item.operateName}
              </Radio>
            ))}
          </Radio.Group>
        </Form.Item>
      </Form>
    </Drawer>
  );
};

export default forwardRef(Edit);
